package com.oncliedisk.administrator.utils;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;

import com.oncliedisk.administrator.DB.Dao;
import com.oncliedisk.administrator.interfaces.OnFileDownListener;
import com.oncliedisk.administrator.model.EntryModel;
import com.oncliedisk.administrator.onlinedisk.R;
import com.vdisk.net.ProgressListener;
import com.vdisk.net.VDiskAPI;
import com.vdisk.net.exception.VDiskDownloadFileExistException;
import com.vdisk.net.exception.VDiskException;
import com.vdisk.net.exception.VDiskIOException;
import com.vdisk.net.exception.VDiskParseException;
import com.vdisk.net.exception.VDiskPartialFileException;
import com.vdisk.net.exception.VDiskServerException;
import com.vdisk.net.exception.VDiskUnlinkedException;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by Administrator on 2015/12/15.
 */
public class DownloadFile extends AsyncTask<Void, Long, Boolean> {
    private Context mContext;
    private final ProgressDialog mDialog;
    private VDiskAPI<?> mApi;
    private String mPath;
    private String mTargetPath;

    private FileOutputStream mFos;

    private boolean mCanceled;
    private long mFileLen;
    private String mErrorMsg;
    private OnFileDownListener mListener;
    private VDiskAPI.VDiskFileInfo info;
    private File file;
    private EntryModel models;

    public DownloadFile(EntryModel model,Context context, VDiskAPI<?> api, String filePath, String targetPath, OnFileDownListener listener) {
        // We set the context this way so we don't accidentally leak activities
        mContext = context.getApplicationContext();
        mApi = api;
        models = model;
        mPath = filePath;
        mTargetPath = targetPath;
        mListener = listener;
        mDialog = new ProgressDialog(context);
        mDialog.setMax(100);
        mDialog.setMessage(mContext.getString(R.string.be_downloading) + " " + filePath);
        mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mDialog.setProgress(0);
        mDialog.setButton(mContext.getString(R.string.be_cancel), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                mCanceled = true;
                mErrorMsg = "Canceled";

                // This will cancel the getFile operation by closing
                // its stream
                if (mFos != null) {
                    try {
                        mFos.close();
                    } catch (IOException e) {
                    }
                }
            }
        });

        mDialog.show();
    }



    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            if (mCanceled) {
                return false;
            }

            file = mApi.createDownloadDirFile(mTargetPath);

            try {
                mFos = new FileOutputStream(file, true);
            } catch (FileNotFoundException e) {
                mErrorMsg = "Couldn't create a local file to store the file";
                return false;
            }

            info = mApi.getFile(mPath, null, mFos, file,
                    new ProgressListener() {

                        @Override
                        public long progressInterval() {
                            return super.progressInterval();
                        }

                        @Override
                        public void onProgress(long bytes, long total) {

                            mFileLen = total;
                            publishProgress(bytes);
                        }
                    });
            if (mCanceled) {
                return false;
            }

            if (info != null) {
                if(models != null){
                    models.setLocalpath(mTargetPath);
                }
                return true;
            }

            return false;

        } catch (VDiskUnlinkedException e) {
            // The AuthSession wasn't properly authenticated or user unlinked.
            mErrorMsg = "Unlinked";
        } catch (VDiskPartialFileException e) {
            // We canceled the operation
            mErrorMsg = "Download canceled";
        } catch (VDiskServerException e) {
            // Server-side exception. These are examples of what could happen,
            // but we don't do anything special with them here.
            if (e.error == VDiskServerException._304_NOT_MODIFIED) {
                // won't happen since we don't pass in revision with metadata
            } else if (e.error == VDiskServerException._401_UNAUTHORIZED) {
                // Unauthorized, so we should unlink them. You may want to
                // automatically log the user out in this case.
            } else if (e.error == VDiskServerException._403_FORBIDDEN) {
                // Not allowed to access this
            } else if (e.error == VDiskServerException._404_NOT_FOUND) {
                // path not found (or if it was the thumbnail, can't be
                // thumbnailed)
            } else if (e.error == VDiskServerException._406_NOT_ACCEPTABLE) {
                // too many entries to return
            } else if (e.error == VDiskServerException._415_UNSUPPORTED_MEDIA) {
                // can't be thumbnailed
            } else if (e.error == VDiskServerException._507_INSUFFICIENT_STORAGE) {
                // user is over quota
            } else {
                // Something else
            }
            // This gets the VDisk error, translated into the user's language
            mErrorMsg = e.body.userError;
            if (mErrorMsg == null) {
                mErrorMsg = e.body.error;
            }
        } catch (VDiskIOException e) {
            // Happens all the time, probably want to retry automatically.
            mErrorMsg = "Network error.  Try again.";
        } catch (VDiskParseException e) {
            // Probably due to VDisk server restarting, should retry
            mErrorMsg = "VDisk error.  Try again.";
        } catch (VDiskDownloadFileExistException e) {
            mErrorMsg = "Download file already exists in your target path.";
            if(models != null){
                models.setLocalpath(mTargetPath);
            }
            return true;
        } catch (VDiskException e) {
            // Unknown error
            mErrorMsg = "Unknown error.  Try again.";
        }
        return false;
    }

    @Override
    protected void onProgressUpdate(Long... progress) {
        Log.d("Test", progress[0] + "/" + mFileLen);
        int percent = (int) (100.0 * (double) progress[0] / mFileLen + 0.5);
        mDialog.setProgress(percent);
    }

    @Override
    protected void onPostExecute(Boolean result) {
        mDialog.dismiss();
        if (result) {
            if(models != null){
                boolean b = Dao.getInstance(mContext).updateDownPath("", models.getLocalpath(), models.getId());
                if(b){
                    mListener.onSuccess(models);
                }else{
                    mListener.onFail("存储失败");
                }
            }else{
                mListener.onSuccess(null);
            }

//            showToast(mContext.getString(R.string.down_url) + ":" + info.getDownloadURL() + "\n"
//                    + "metadata:" + info.getMetadata().fileName());
        } else {
            // Couldn't download it, so show an error
            mListener.onFail(mErrorMsg);
        }
    }

    private void showToast(String msg) {
        Toast error = Toast.makeText(mContext, msg, Toast.LENGTH_LONG);
        error.show();
    }
}
